package com.warski.wonderfires.view;

import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.SweepGradient;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.warski.wonderfires.TheApplication;

public class ColorDiskView extends View {
    private Paint mDiskPaint;//色盘画笔
    private Paint mInDiskPaint;//内圆画笔
    private Paint mInInDiskPaint;//最内圆画笔
    private float mDiskPaintWidth;//色盘宽度
    private float mDiskPoint;//圆点宽度
    private Paint mPointPaint;//圆点画笔
    private Paint mArcPaint;//圆弧画笔
    private Shader shader; // 色环颜色的发散位置
    private Paint bgPaint;//背景画笔
    private float r_bgPaint;//背景圆半径
    private float r_shaderPaint;//
    private float centerX;// 圆心X
    private float centerY;// 圆心Y
    private static int mColor = Color.RED;//当前选择颜色
    private int radius;//最内圆半径
    private RectF oval;//圆弧外形定义
    private static float degrees = 0f;// 圆点相对最开始（355,0）运动角度
    private int[] mCircleColors = {0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000};//渐变色环颜色
    private float[] colorPotXY = new float[2]; // 白点坐标
    private static float markPointX;//当前滑动点x坐标
    private static float markPointY;//当前滑动点Y坐标

    public ColorDiskView(Context context) {
        super(context);
        init();
    }

    public ColorDiskView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ColorDiskView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {

        mDiskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mDiskPaint.setStyle(Paint.Style.STROKE);

        shader = new SweepGradient(0, 0, mCircleColors, null);
        mDiskPaint.setShader(shader);

        bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        int length = TheApplication.width*2/3;
        LinearGradient gradient = new LinearGradient(0, 0, length, length, 0XFF222222, 0xFF909090, Shader.TileMode.CLAMP);
        bgPaint.setShader(gradient);

        mInInDiskPaint = new Paint();

        mInDiskPaint = new Paint();

        mPointPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mArcPaint = new Paint();
        //取消锯齿
        mArcPaint.setAntiAlias(true);
        mArcPaint.setStyle(Paint.Style.STROKE);
        mArcPaint.setStrokeWidth(5);
        mArcPaint.setShader(shader);
        length = (length - 40)/2;
        oval = new RectF( -length, -length,
                length, length);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        int length = TheApplication.width*2/3;

        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(length, length);
            radius = length*8/75;
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(length, heightSpecSize);
            radius = length*8/75;
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize, length);
            radius = widthSpecSize / 10;
        }

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();
        final int paddingTop = getPaddingTop();
        final int paddingBottom = getPaddingBottom();
        int width = getWidth() - paddingLeft - paddingRight;
        int height = getHeight() - paddingTop - paddingBottom;
        //平移，将画布的坐标原点向左右方向移动width / 2，向上下方向移动height / 2
        canvas.translate(width >> 1, height >> 1);
        centerX = Math.min(width, height) >> 1;
        centerY = height >> 1;
        r_bgPaint = centerX - 45;
        mDiskPaintWidth = r_bgPaint / 12 * 5;
        mDiskPoint = mDiskPaintWidth / 8;
        r_shaderPaint = r_bgPaint - mDiskPaintWidth / 2;
        mDiskPaint.setStrokeWidth(mDiskPaintWidth);
        colorPotXY[0] = centerX - 20;
        colorPotXY[1] = 0;

        //画最外圆
        canvas.drawCircle(0, 0, r_bgPaint, bgPaint);
        //画色盘
        canvas.drawCircle(0, 0, r_shaderPaint, mDiskPaint);

        // 获取当前对应颜色
        int color = getColor();
        mInInDiskPaint.setColor(color);
        //画最内圆
        canvas.drawCircle(0, 0, radius, mInInDiskPaint);

        int[] colors = {color, color, Color.TRANSPARENT};
        RadialGradient gradient = new RadialGradient(0, 0, radius + 60, colors, null, Shader.TileMode.CLAMP);
        mInDiskPaint.setShader(gradient);
        //画内圆渐变
        canvas.drawCircle(0, 0, radius + 60, mInDiskPaint);

        if (markPointX == 0 && markPointY == 0) {
            markPointX = colorPotXY[0];
            markPointY = colorPotXY[1];
        }
        // 画弧线
        canvas.drawArc(oval,-150 + degrees,150,false,mArcPaint);

        mPointPaint.setColor(color);
        // 画圆点
        canvas.drawCircle(markPointX, markPointY, mDiskPoint, mPointPaint);

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                moved(x, y);
                break;

            case MotionEvent.ACTION_MOVE:
                moved(x, y);
                //获取角度
                //获取选中的颜色
                mColor = calculateColor(calculateAngle(x, y));
                break;

            case MotionEvent.ACTION_UP:
                moved(x, y);
                //获取角度
                float angle = calculateAngle(x, y);
                //获取选中的颜色
                mColor = calculateColor(angle);

                break;
            default:
                break;
        }

        return true;
    }

    private float calculateAngle(float x, float y) {
        return (float) Math.atan2(y - centerY, x - centerX);
    }

    private int calculateColor(float angle) {
        float unit = (float) (angle / (2 * Math.PI));
        if (unit < 0) {
            unit += 1;
        }

        if (unit <= 0) {
            mColor = mCircleColors[0];
            return mCircleColors[0];
        }
        if (unit >= 1) {
            mColor = mCircleColors[mCircleColors.length - 1];
            return mCircleColors[mCircleColors.length - 1];
        }

        float p = unit * (mCircleColors.length - 1);
        int i = (int) p;
        p -= i;

        int c0 = mCircleColors[i];
        int c1 = mCircleColors[i + 1];
        int a = ave(Color.alpha(c0), Color.alpha(c1), p);
        int r = ave(Color.red(c0), Color.red(c1), p);
        int g = ave(Color.green(c0), Color.green(c1), p);
        int b = ave(Color.blue(c0), Color.blue(c1), p);
        Log.i("rgb", "rgb" + r + ":" + g + ":" + b);

        Intent intent = new Intent("color");
        intent.putExtra("red", r);
        intent.putExtra("green", g);
        intent.putExtra("blue", b);
        getContext().sendBroadcast(intent);
        mColor = Color.argb(a, r, g, b);
        return Color.argb(a, r, g, b);
    }

    private int ave(int s, int d, float p) {
        return s + Math.round(p * (d - s));
    }



    private void moved(float x, float y) {

        int length = TheApplication.width*2/3;
        if (x > length/2){
            markPointX = (float) Math.sqrt(Math.pow(centerX -20, 2) / ((Math.pow((y - centerY), 2)/Math.pow((x - centerX), 2)) + 1));
            markPointY = ((y - centerY) / (x - centerX)) * markPointX;
        }else {
            markPointX = -(float) Math.sqrt(Math.pow(centerX -20, 2) / ((Math.pow((centerY - y), 2)/Math.pow((centerX - x), 2)) + 1));
            markPointY = ((centerY - y) / (centerX - x)) * markPointX;
        }

        length = length - 40;
        double sqrt = Math.sqrt(Math.pow((markPointX - length/2), 2) + Math.pow((markPointY), 2));
        double sqrt1 = Math.sqrt(Math.pow((length/2), 2) + Math.pow((length/2), 2));

        double asin = Math.asin(sqrt / length);
        double asin2 = Math.asin(sqrt1 / length);

        if (markPointY <= 0){
            degrees = -(float) (asin * 2 * 180 / (float)Math.PI);
        }else {
            degrees = (float) (asin * 2 * 180 / (float)Math.PI);
        }

        invalidate();
    }

    public int getColor() {
        return mColor;
    }

}
